package cn.coisini.utils;

import cn.coisini.model.common.enums.ResultEnum;
import cn.coisini.model.common.exception.CustomAuthenticationException;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


/**
 * @author xiangshaw
 * Description: MD5加密
 */
public class MD5Util {

    private MD5Util() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * MD5加密
     */
    public static String encryption(String str) {
        try {
            // 创建 MessageDigest 对象，指定使用 MD5 算法
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 使用指定的 byte 数组更新摘要（数组由 str 转换）
            md.update(str.getBytes());
            // 完成哈希计算 获取密文（MD5 的长度固定为 16 字节）
            byte[] bytes = md.digest();
            // 调用方法将数组转换为十六进制字符串
            StringBuilder hashBuilder = convertToHexString(bytes);
            // 返回十六进制字符串
            return hashBuilder.toString();
        } catch (NoSuchAlgorithmException e) {
            // 抛出运行时加密异常
            throw new CustomAuthenticationException(ResultEnum.FAIL, e.getMessage());
        }
    }

    private static StringBuilder convertToHexString(byte[] bytes) {
        // 创建 StringBuilder 对象 保存十六进制字符串
        StringBuilder hashBuilder = new StringBuilder();
        // 遍历bytes数组
        for (byte mdByte : bytes) {
            // 将字节转换为正整数，避免转换为负数，并转换为十六进制字符串
            int temp = mdByte & 0xff;
            if (temp < 0x10) {
                // 如果字节小于 0x10，则在十六进制字符串前面补 0
                hashBuilder.append("0");
            }
            // 将字节转换为十六进制字符串，并添加到 StringBuilder 对象中
            hashBuilder.append(Integer.toHexString(temp));
        }
        // 返回十六进制字符串
        return hashBuilder;
    }

    /**
     * MD5加盐加密
     */
    public static String encodeWithSalt(String password, String salt) {
        // 对密码进行 MD5 加盐加密
        return encryption(encryption(password) + salt);
    }
}
